﻿using Microsoft.Win32;
using System.IO;

namespace AutoUpdate
{
    class FileZip
    {
        /// <summary>
        /// 文件解压缩
        /// </summary>
        /// <param name="zipSrc"></param>
        /// <param name="filesrc2"></param>
        public FileZip(string zipSrc, string filesrc2)
        {
            try
            {
                //var archive = ArchiveFactory.Open(zipSrc);
                //foreach (var entry in archive.Entries)
                //{
                //    if (!entry.IsDirectory)
                //    {
                //        Console.WriteLine(entry.FilePath);
                //        entry.WriteToDirectory(filesrc2, ExtractOptions.ExtractFullPath | ExtractOptions.Overwrite);
                //    }
                //}
                //archive.Dispose();

                UseWinRar rar = new UseWinRar();
                //string[] zipFiles = Directory.GetFiles(Environment.CurrentDirectory, "*.zip");//获取所有zip文件路径 
                //foreach (string zipFile in zipFiles)
                //{
                    rar.unZipToCurrentDirectory(zipSrc);
                //}

                //using (Stream stream = File.OpenRead(zipSrc))
                //{
                //    var reader = ReaderFactory.Open(stream);
                //    while (reader.MoveToNextEntry())
                //    {
                //        if (!reader.Entry.IsDirectory)
                //        {
                //            Console.WriteLine(reader.Entry.FilePath);
                //            reader.WriteEntryToDirectory(filesrc2, ExtractOptions.ExtractFullPath | ExtractOptions.Overwrite);
                //        }
                //    }
                //}
                //System.Windows.Forms.MessageBox.Show("覆盖历史版本完成");
            }
            catch //(Exception se)
            {
                //System.Windows.Forms.MessageBox.Show("覆盖历史版本异常");
            }
        }

      
    }

    class UseWinRar
    {
        private string rarExeFile = null;//WinRar.exe路径 
        private bool useAble = false;//标志WinRar是否可用 

        public UseWinRar()//构造方法 
        {
            rarExeFile = getRarExe();
            useAble = !string.IsNullOrEmpty(rarExeFile);//如果WinRar.exe路径不为空，说明可用 
        }

        public static string getRarExe()//获取WinRar所在磁盘路径 
        {
            string rarExe = null;
            RegistryKey regKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\WinRAR.exe");
            if (regKey == null)
            {
                return null;
            }
            rarExe = regKey.GetValue("").ToString();
            regKey.Close();//关闭注册表 
            return rarExe;
        }

        public bool exeRarCmd(string cmd)//执行某个命令 
        {
            //if (!useAble)
            //{
            //    return false;
            //}
            //Process process = new Process();//新建一个过程 
            //ProcessStartInfo startInfo = new ProcessStartInfo(rarExeFile);//新建一个启动信息 
            //startInfo.Arguments = cmd;//设置启动信息的执行参数 
            //                          //startInfo.WorkingDirectory = workDirectory;//设置启动信息的工作目录 
            //startInfo.WindowStyle = ProcessWindowStyle.Hidden;//设置程序后台运行 
            //process.StartInfo = startInfo;//设置过程的启动信息 
            //process.Start();//开始过程 
            //return true;

            System.Diagnostics.Process p = new System.Diagnostics.Process();
            p.StartInfo.FileName = "cmd.exe";
            p.StartInfo.UseShellExecute = false;    //是否使用操作系统shell启动
            p.StartInfo.RedirectStandardInput = true;//接受来自调用程序的输入信息
            p.StartInfo.RedirectStandardOutput = true;//由调用程序获取输出信息
            p.StartInfo.RedirectStandardError = true;//重定向标准错误输出
            p.StartInfo.CreateNoWindow = true;//不显示程序窗口
            p.Start();//启动程序

            //向cmd窗口发送输入信息
            p.StandardInput.WriteLine(cmd + "&exit");

            p.StandardInput.AutoFlush = true;
            //p.StandardInput.WriteLine("exit");
            //向标准输入写入要执行的命令。这里使用&是批处理命令的符号，表示前面一个命令不管是否执行成功都执行后面(exit)命令，如果不执行exit命令，后面调用ReadToEnd()方法会假死
            //同类的符号还有&&和||前者表示必须前一个命令执行成功才会执行后面的命令，后者表示必须前一个命令执行失败才会执行后面的命令



            //获取cmd窗口的输出信息
            string output = p.StandardOutput.ReadToEnd();

            //StreamReader reader = p.StandardOutput;
            //string line=reader.ReadLine();
            //while (!reader.EndOfStream)
            //{
            //    str += line + "  ";
            //    line = reader.ReadLine();
            //}

            p.WaitForExit();//等待程序执行完退出进程
            p.Close();


            return true;
        }

        public bool unZipAll(string zipFile, string targetDirectory)//将指定压缩文件解压到指定目录 
        {
            if (!File.Exists(zipFile))
            {
                return false;
            }
            //string zipCmd = "x " + zipFile + " " + targetDirectory + " -y -ibck";//后台解压压缩文件中全部文件到指定目录 

            //string zipCmd = targetDirectory.Split(':')[0] + ":&cd " + targetDirectory  + "&unrar.exe x -y  " +zipFile;
            string zipCmd = $@"cd {targetDirectory}&unrar.exe e -y ""{zipFile}"" ""{targetDirectory}""";
            exeRarCmd(zipCmd);//执行解压操作 
            return true;
        }

        public bool unZipToCurrentDirectory(string zipFile)//将压缩文件解压到当前目录 
        {
            if (!File.Exists(zipFile))
            {
                return false;
            }
            FileInfo fileInfo = new FileInfo(zipFile);
            return unZipAll(zipFile, fileInfo.DirectoryName);
        }
    }
}
